﻿/*
    UploadFile.as
    Copyright (c) Otávio Ribeiro<otavio@otavio.eng.br> @ 2008
    
    This file is part of OtaSwfUploader application.

    Birthday is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Birthday is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package
{
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	import flash.events.EventDispatcher;
	import flash.events.Event;
	import flash.events.DataEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.HTTPStatusEvent;
	import flash.events.ProgressEvent;
	import flash.events.IOErrorEvent;
	
	import ExternalCall;
	
	class UploadFile extends EventDispatcher
	{
		private var fileId:Number;
		private var file:FileReference;
		private var urlRequest:URLRequest;
		private var urlVariables:URLVariables;
		private var fileStatus:Number;
		private var externalCall:ExternalCall;
		private var imageFieldName: String;
		
		private var lastProgressTime:Date = null;
		
		public static const STATUS_PENDING:Number = 0;
		public static const STATUS_UPLOADING:Number = 1;
		public static const STATUS_REMOVED:Number = 2;
		public static const STATUS_COMPLETED:Number = 3;
		public static const STATUS_ERROR:Number = 4;
		public static const STATUS_UPLOAD_COMPLETED:Number = 5;

		
		private var params:Object = {};
		
		public function UploadFile(fileId:Number, file:FileReference, postUrl:String, movieName:String, imageFieldName:String)
		{
			this.fileId = fileId;
			this.file = file;
			this.urlRequest = new URLRequest(postUrl);
			this.urlVariables = new URLVariables();
			this.fileStatus = UploadFile.STATUS_PENDING;
			this.imageFieldName = imageFieldName;

			this.file.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
			this.file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);			
			this.file.addEventListener(Event.OPEN,openHandler);
			this.file.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			this.file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
			this.file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteHandler);
			this.file.addEventListener(Event.COMPLETE, completeHandler);
			
			this.externalCall = new ExternalCall(movieName);
		}
		
		public function get Status():Number
		{
			return this.fileStatus;
		}
		
		public function set Status(value):void 
		{
			this.fileStatus = value;
		}
		
		public function addRequestParameter(key,value)
		{
			this.urlVariables[key] = value;
		}
		
		public function get UrlRequest():URLRequest
		{
			return this.urlRequest;
		}
		
		public function get FileRef():FileReference
		{
			return this.file;
		}
		
		public function get FileId():Number
		{
			return this.fileId;
		}
		
		public function startUpload():void
		{
			this.urlRequest.data = this.urlVariables;
			this.file.upload(this.urlRequest,this.imageFieldName);
		}
		
		public function toJsObject():Object
		{
			var info:Object = {
				id: this.fileId,
				name: file.name,
				size: file.size,
				status: this.fileStatus
			}			
			
			return info;
		}
		private function httpStatusHandler(ev:HTTPStatusEvent)
		{
			var statusCode = ev.status;
			
			var info:Object = {
				statusCode: statusCode
			};
			
			if(this.fileStatus != STATUS_COMPLETED){
				this.fileStatus = UploadFile.STATUS_ERROR;				
				this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_STATUS_ERROR,info);
			}
		}
		
		private function ioErrorHandler(ev:IOErrorEvent)
		{
			var text:String = ev.text;
			
			var info:Object = {
				text: text
			};
			
			if(this.fileStatus != STATUS_COMPLETED){
				this.fileStatus = UploadFile.STATUS_ERROR;				
				this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_IO_ERROR,info);
			}
		}
		
		private function openHandler(ev:Event)
		{
			var info:Object = {
			};
			
			this.fileStatus = STATUS_UPLOADING;
			this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_OPEN,info);
		}
		
		private function progressHandler(ev:ProgressEvent)
		{
			var bytesTotal:Number = ev.bytesTotal;
			var bytesLoaded:Number = ev.bytesLoaded;
			
			var info:Object = {
				bytesLoaded: bytesLoaded,
				bytesTotal: bytesTotal
			}
			
			this.fileStatus = STATUS_UPLOADING;
			this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_PROGRESS,info);
		}
		
		private function securityErrorHandler(ev:SecurityErrorEvent)
		{
			var text:String = ev.text;
			
			var info:Object = {
				text: text
			};
			
			if(this.fileStatus != STATUS_COMPLETED){
				this.fileStatus = UploadFile.STATUS_ERROR;				
				this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_SECURITY_ERROR,info);			
			}
		}
		
		private function uploadCompleteHandler(ev:DataEvent)
		{
			var response:String = ev.data;
			
			var info:Object = {
				response: response
			};
			
			this.fileStatus = UploadFile.STATUS_UPLOAD_COMPLETED;
			this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_UPLOAD_COMPLETE,info);
		}
		
		private function completeHandler(ev:Event)
		{
			var info:Object = {
			};
			
			this.fileStatus = UploadFile.STATUS_COMPLETED;
			this.externalCall.dispatchOnUploadNotify(this.FileId, MainDocument.NOTIFY_COMPLETE,info);			
		}		
	}
}